package entity;

import java.io.Serializable;

/**
 * This is the Word class.  
 */
public class Word extends Movable implements Serializable {
	private static final long serialVersionUID = -7284525702101985488L;
	private static int nextId = 0;

	public int id;
	
	public String value;
	public WordType wordType;
	public int x;
	public int y;
	public int height;
	public int width;
	
	public boolean blink;

	/**
	 * Constructor of Word. 
	 * A word consists of id, value(v), wordType, position(x and y), height and width.
	 */
	public Word(int id, String v, WordType wordType, int x, int y, int height, int width) {
		this.id = id;
		this.value = v;
		this.wordType = wordType;
		this.x = x;
		this.y = y;
		this.height = height;
		this.width = width;
		blink = false;
	}
	
	/**
	 * Constructor of Word. A word with id, value(v) and wordType.
	 * Other values are set as default.
	 */
	public Word(int id, String v, WordType wordType) {
		this.id = id;
		this.value = v;
		this.wordType = wordType;
		
		this.x = 0;
		this.y = 0;
		this.height = 0;
		this.width = 0;
		blink = false;
	}

	/**
	 * Constructor of Word. A word already has attributes.
	 */
	public Word(Word w) {
		this.id = w.getId();
		this.value = w.getValue();
		this.wordType = w.getWordType();
		this.x = w.getX();
		this.y = w.getY();
		this.height = w.getHeight();
		this.width = w.getWidth();
		blink = false;
	}
	
	public Word clone(){
		return new Word(this);
	}
	
	/**
	 * Update the position of a word.
	 */
	public void updatePosition(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	/**
	 * Check whether the word is in a specific area.
	 */
	public boolean contains(int x, int y) {
		return (x >= this.x && x < (this.x + this.width))
				&& (y >= this.y && y < (this.y + this.height));
	}
	
	/**
	 * Check whether a word overlaps another word.
	 */
	public boolean checkCollision(Word w) { 
		return (w != this && Math.abs(w.getY() - this.getY()) <= w.getHeight()
				&& ((w.getX() + w.getWidth() > this.getX() && w.getX() <= this.getX())
				|| (this.getX() + this.getWidth() > w.getX() && this.getX() <= w.getX())));
	}
	
	/**
	 * Check whether a word is equals to another word, in terms of not only value, but also all other attributes. 
	 */
	@Override
	public boolean equals(Object o) {
		return o instanceof Word && id == ((Word) o).getId();
	}
	
	/**
	 * Return the string value of an word.
	 */
	public String toString() {
		return value;
	}
	
	/**
	 * Return the height of a word.
	 */
	public int getHeight() {
		return height;
	}
	
	/**
	 * Set height for a word.
	 */
	public void setHeight(int height) {
		this.height = height;
	}
	
	/**
	 * Return the width of a word.
	 */
	public int getWidth() {
		return width;
	}
	
	/**
	 * Set width for a word.
	 */
	public void setWidth(int width) {
		this.width = width;
	}
	
	/**
	 * Set position for a word.
	 */
	public void setPosition(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	/**
	 * Get the position of X direction of a word.
	 */
	public int getX() {
		return x;
	}
	
	/**
	 * Set the position of X direction for a word.
	 */
	public void setX(int x) {
		this.x = x;
	}
	
	/**
	 * Get the position of Y direction of a word.
	 */
	public int getY() {
		return y;
	}
	
	/**
	 * Set the position of Y direction for a word.
	 */
	public void setY(int y) {
		this.y = y;
	}
	
	/**
	 * Return the value of a word.
	 */
	public String getValue() {
		return value;
	}
	
	/**
	 * Return the wordType of a word.
	 */
	public WordType getWordType() {
		return wordType;
	}

	/**
	 * Return the ID of a word.
	 */
	public int getId() {
		return id;
	}

	/**
	 * Set ID for a word.
	 */
	public void setId(int id) {
		this.id = id;
	}
	
	public static int nextId(){
		return nextId++;
	}
}
